<?php
/**
 * Created by PhpStorm.
 * User: longli
 * Date: 2021/09/30
 * Time: 11:52
 * @link http://www.lmterp.cn
 */

namespace app\common\service\orders;

use app\common\library\Tools;
use app\common\model\OrdersRules;
use app\common\model\OrdersRulesGroup;
use app\common\service\BaseService;
use think\facade\Validate;

/**
 * 验证录入规则信息
 * Class ValidateRulesService
 * @package app\common\service\orders
 */
class ValidateRulesService extends BaseService
{
    /**
     * 验证规则组
     * @param array $group 规则组
     * @return bool|string
     * @date 2021/08/31
     * @author longli
     */
    public function validateGroup(& $group)
    {
        $table = OrdersRulesGroup::getTable();
        $validate = Validate::make([
            'group_name' => "require|unique:{$table},group_name",
        ],[
            'group_name.require'  => '分组名称必填',
            'group_name.unique'   => '分组名称已存在',
        ]);
        if(!$validate->batch()->check($group)) return join(', ', $validate->getError());
        return true;
    }

    /**
     * 验证规则
     * @param array $rules 规则
     * @return bool|string
     * @date 2021/08/31
     * @author longli
     */
    public function validateRules(& $rules = [])
    {
        $validate = Validate::make([
            'rule_type'       => "require",
            'condition'       => "require",
            'rule_value'      => "require",
            'match_type'      => "require",
            'list_id'         => "require",
        ],[
            'rule_type.require'    => '匹配规则必选',
            'condition.require'    => '条件必选',
            'rule_value.require'   => '值必填',
            'match_type.require'   => '下一条匹配方式必选',
            'list_id.require'      => '指定项必选',
        ]);
        $index = array_keys($rules)[0];
        $validateData = [];
        $fields = ['rule_type', 'rule_value', 'condition', 'match_type', 'list_id', 'remark', 'rule_id', 'is_include'];
        foreach($rules[$index] as $k => $v)
        {
            $temp = [];
            foreach($fields as $field)
            {
                if(in_array($field, ['rule_id']) && empty($rules[$field][$k])) continue;
                $temp[$field] = isset($rules[$field][$k])
                    ? $rules[$field][$k]
                    : '';
            }
            $validateData[] = $temp;
        }
        $error = [];
        $checkRules = [
            OrdersRules::CONDITION_EGT, OrdersRules::CONDITION_GT,
            OrdersRules::CONDITION_ELT, OrdersRules::CONDITION_LT,
        ];
        $replaceRules = [OrdersRules::CONDITION_IN, OrdersRules::CONDITION_NOT_IN];
        $unique = []; // 验证唯一性
        $last = count($validateData);
        foreach($validateData as $k => & $v)
        {
            $next = $k + 1;
            $v['next_node'] = $last == $next ? 0 : $next;
            if(!$validate->batch()->check($v)) $error[] = join(', ', $validate->getError());
            if(in_array($v['condition'], $checkRules))
            {
                if(!is_numeric($v['rule_value']))
                    $error[] = "【{$v['rule_value']}】必须为数字";
            }
            else if($v['condition'] == OrdersRules::CONDITION_BETWEEN)
            {
                if(preg_match('/^(\d+)[-,](\d+)$/', $v['rule_value'], $matches))
                {
                    if($matches[1] >= $matches[2])
                        $error[] = "范围【{$v['rule_value']}】左值比右值大";
                }
                else
                {
                    $error[] = "范围【{$v['rule_value']}】格式有误";
                }
            }
            else if(in_array($v['condition'], $replaceRules))
            {
                $v['rule_value'] = replaceStr($v['rule_value']);
            }
            // 检查重复配置
            $keyIn = $v['rule_type'] . $v['is_include'];
            in_array($keyIn, $unique)
                ? $error[] = sprintf("重复配置【%s】", OrdersRules::$RULE_TYPE[$v['rule_type']])
                : $unique[] = $keyIn;

            // 检查平台, 账号, 国家, SPU, SKU
            if(empty($v['rule_value'])) continue;
            $ruleValue = explode(',', replaceStr($v['rule_value']));
            $validateCodeMsg = "";
            $validateCode = [];
            switch($v['rule_type'])
            {
                case OrdersRules::RULE_TYPE_PLATFORM:
                    $validateCode = \app\common\model\AccountPlatform::whereIn("code", $ruleValue)
                        ->column("code");
                    $validateCodeMsg = "平台编码【%s】不存在";
                    break;
                case OrdersRules::RULE_TYPE_ACCOUNT:
                    $validateCode = \app\common\model\Account::whereIn("username", $ruleValue)
                        ->column("username");
                    $validateCodeMsg = "账号【%s】不存在";
                    break;
                case OrdersRules::RULE_TYPE_COUNTRY:
                    $validateCode = \app\common\model\SysCountries::whereIn("code_two", $ruleValue)
                        ->column("code_two");
                    $validateCodeMsg = "国家代码【%s】不存在";
                    break;
                case OrdersRules::RULE_TYPE_SPU:
                    $validateCode = \app\common\model\Product::whereIn("spu", $ruleValue)
                        ->column("spu");
                    $validateCodeMsg = "SPU【%s】不存在";
                    break;
                case OrdersRules::RULE_TYPE_SKU:
                    $validateCode = \app\common\model\ProductStore::whereIn("sku", $ruleValue)
                        ->column("sku");
                    $validateCodeMsg = "SKU【%s】不存在";
                    break;
            }
            if(!empty($validateCodeMsg) && ($diffCode = Tools::getArrayDiff($ruleValue, $validateCode)))
                $error[] = sprintf($validateCodeMsg, join(', ', $diffCode));
        }
        if(!empty($error)) return join(', ', $error);
        $rules = $validateData;
        return true;
    }
}